#pragma once


#include<iostream>
#include<cstring>
#include<functional>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<sys/wait.h>
#include<signal.h>
#include<pthread.h>
#include"err.hpp"
#include"ThreadPool.hpp"
#include"Task.hpp"
#include"log.hpp"

namespace ns_server
{
    static const uint16_t defaultport=8081;
    static const int backlog=32;
    using func_t=std::function<std::string(const std::string&)>;
    class TcpServer;
    class ThreadData
    {
    public:
        ThreadData(int fd,const std::string& ip,const uint16_t &port,TcpServer* ts)
        :sock(fd),clientip(ip),clientport(port),current(ts)
        {}
        int sock;
        std::string clientip;
        uint16_t clientport;
        TcpServer* current;
    };
    
    class TcpServer
    {
    public:
    TcpServer(func_t func,uint16_t port=defaultport):func_(func),port_(port),quit_(true)
    {

    }
    ~TcpServer()
    {

    }
    void initServer()
    {
        //1.创建socket，文件
        listensock_=socket(AF_INET,SOCK_STREAM,0);
        if(listensock_<0)
        {
            std::cerr<<"create socket error"<<std::endl;
            exit(SOCKET_ERR);
        }
        //2.绑定bind
        //2.1定义sockaddr_in结构体 初始化各个字段
        struct sockaddr_in local;
        memset(&local,0,sizeof(local));
        local.sin_family=AF_INET;
        local.sin_port=htons(port_);
        local.sin_addr.s_addr=htonl(INADDR_ANY);
        //2.2bind
        if(bind(listensock_,(struct sockaddr*)&local,sizeof(local))<0)
        {
            std::cerr<<"bind socket error"<<std::endl;
            exit(BIND_ERR);
        }
        //3.监听
        if(listen(listensock_,backlog)<0)
        {
            std::cerr<<"listen socket error"<<std::endl;
            exit(LISTEN_ERR);
        }
    }
    void start()
    {
        signal(SIGCHLD,SIG_IGN);
        quit_=false;
        while (!quit_)
        {
           //4.获取链接，accept
           struct sockaddr_in client;
           socklen_t len=sizeof(client);
           sleep(1);
           int sock=accept(listensock_,(struct sockaddr*)&client,&len);
           if(sock<0)
           {
            std::cerr<<"accept error"<<std::endl;
            continue;
           }
           std::string clientip=inet_ntoa(client.sin_addr);
           uint16_t clientport=ntohs(client.sin_port);
           //5.获取链接成功
           std::cout<<"获取链接成功:"<<sock<<"from"<<listensock_<<","<<clientip<<"-"<<clientport<<std::endl;
           logMessage(Info,"获取连接成功：%d from %d ,who: %s-%d",sock,listensock_,clientip.c_str(),clientport);
           //service(sock,clientip,clientport);
        //    pid_t id=fork();
        //    if(id<0){
        //     close(sock);
        //     continue;
        //    }
        //    else if(id==0)
        //    {
        //     //child,父进程fd会被child继承 子进程会拷贝父进程文件描述符表
        //     //子进程业务处理 父进程监听
        //     //子进程建议关闭不需要的fd
        //     close(listensock_);
        //     service(sock,clientip,clientport);



        //     exit(0);
        //    }
        //    //父进程 一定要关闭不需要的fd(文件描述符泄露)
        //    close(sock);
        //    pid_t ret=waitpid(id,nullptr,0);//阻塞等待
        //    if(ret==id) std::cout<<"wait child"<<id<<"succes"<<std::endl;
        // 
        //线程池————————————————
        Task t(sock,clientip,clientport,std::bind(&TcpServer::service,this,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3));
        ThreadPool<Task>::getinstance()->pushTask(t);

        }

    }
    static void* threadRoutine(void* args)
    {
        pthread_detach(pthread_self());
        ThreadData* td=static_cast<ThreadData*>(args);
        td->current->service(td->sock,td->clientip,td->clientport);
        delete td;
        return nullptr;
    }
    void service(int sock,const std::string& clientip,const uint16_t &clientport)
    {
        // v2
            std::string who = clientip + "-" + std::to_string(clientport);
            char buffer[1024];

            ssize_t s = read(sock, buffer, sizeof(buffer) - 1); // recv TODO
            if (s > 0)
            {
                buffer[s] = 0;
                std::string res = func_(buffer); // 进行回调
                // std::cout << who << ">>> " << res << std::endl;
                logMessage(Debug, "%s# %s", who.c_str(), res.c_str());
                write(sock, res.c_str(), res.size());
            }
            else if (s == 0)
            {
                // 对方将连接关闭了
                // std::cout << who << " quit, me too" << std::endl;
                logMessage(Info, "%s quit,me too", who.c_str());
            }
            else
            {
                // std::cerr << "read error: " << strerror(errno) << std::endl;
                logMessage(Error, "read error, %d:%s", errno, strerror(errno));
            }
            close(sock);
        // char buffer[1024];
        // while (true)
        // {
        //     ssize_t s=read(sock,buffer,sizeof(buffer)-1);
        //     if(s>0)
        //     {
        //         buffer[s]=0;
        //         std::string res=func_(buffer);
        //         std::cout<<buffer<<std::endl;
        //         write(sock,res.c_str(),res.size());
        //     }
        //     else if(s==0)
        //     {
        //         close(sock);
        //         std::cout<<"quit"<<std::endl;
        //         break;
        //     }
        //     else{
        //         close(sock);
        //         std::cerr<<"read error:"<<strerror(errno)<<std::endl;
        //     }
        // }
        
    }


    private:
        uint16_t port_;
        int listensock_;//监听套接字
        bool quit_;
        func_t func_;

    };
}